﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading;
using DevExpress.XtraCharts;
using MathWorks.MATLAB.NET.Arrays;
using TankMath;
using System.Windows.Forms;
using Series = DevExpress.XtraCharts.Series;

namespace TankControl
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            _tankMathLib = new TankMathLib();
            
        }

        private static TankMathLib _tankMathLib;

        private void TrackBar1ValueChanged(object sender, EventArgs e)
        {

        }

        private int _counter;
        private void Timer1Tick(object sender, EventArgs e)
        {
            if (_counter > t1.Count - 1)
            {
                timer1.Stop();
                return;
            }
            try
            {
                tank1.Level = t2[_counter] * 4;
                tank2.Level = t1[_counter] * 4;
            }
            catch (Exception)
            {
                timer1.Stop();
                MessageBox.Show("Бак переполнен!", "Авария!", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }
            
            progressBar1.Increment(1);
            _counter++;
        }

        private void trackBar2_ValueChanged(object sender, EventArgs e)
        {
            tank2.Level = trackBar2.Value;
        }

        private List<int> t1;
        private List<int> t2;
        private DataTable table;
        private void Button1Click(object sender, EventArgs e)
        {
            
            if (tank1.Level != trackBar1.Value)
            {
                table = new DataTable();
                progressBar1.Value = 0;
                var time = new double[] { 0, TimeTrackBar.Value };
                var values = new double[]
                    {
                        0, tank2.Level/4.0, tank1.Level/4.0, 1, 1, 0, CockTrackBar1.Value/10.0f, CockTrackBar2.Value/10.0f,
                        trackBar1.Value/4.0, 4, 4, kpTrackBar.Value/10.0f, tauTrackBar.Value
                    };
                try
                {
                    var result = _tankMathLib.pr2(new MWNumericArray(time), new MWNumericArray(values));
                    var array = (double[,])(((MWStructArray)result)["y"].ToArray());
                    t1 = new List<int>();
                    t2 = new List<int>();
                   
                    
                    for (int i = 0; i < 6; i++)
                    {
                        table.Columns.Add(i.ToString(), typeof (double));
                    }

                    for (int i = 0; i < array.GetLength(1); i++)
                    {

                        DataRow row = table.NewRow();
                        row[0] = Math.Floor(array[0, i]);
                        row[1] = Math.Floor(array[1, i]);
                        row[2] = Math.Floor(array[2, i]);
                        row[3] = Math.Floor(array[3, i]);
                        row[4] = Math.Floor(array[4, i]);
                        row[5] = Math.Floor(array[5, i]);
                        t1.Add((int)array[1, i]);
                        t2.Add((int)array[2, i]);
                        table.Rows.Add(row);
                    }
                    
                    progressBar1.Maximum = t1.Count;
                }
                catch (Exception exception)
                {

                    MessageBox.Show("Некорректные настройки регулятора!\nНастройте регулятор и попробуйте еще раз.",
                                    "Предупреждение!", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                    return;
                }

                _counter = 0;
                timer1.Start();
            }
        }

        private List<string> tempCol = new List<string>()
            {
                {"Время"},
                {"Уровень в емкости 1, см."},
                {"Уровень в емкости 2, см."},
                {"Возмущение"},
                {"Управляющее воздествие"},
                {"Критерий качества регулирования"}
            }; 
        private Dictionary<string, int> columnsName = new Dictionary<string, int>()
            {
                {"Время", 0},
                {"Уровень в емкости 1", 1},
                {"Уровень в емкости 2", 2},
                {"Возмущение", 3},
                {"Управляющее воздествие", 4},
                {"Критерий качества регулирования", 5}
            }; 
        private void ToolStripButtonClick(object sender, EventArgs e)
        {
            if (table == null) return;
            
            var button = (ToolStripButton)sender;

            if (columnsName.ContainsKey(button.Text))
            {
                chartControl1.Series.Clear();

                var resultTable = NewTable(table, 0, columnsName[button.Text], "Время", button.Text);

                chartControl1.DataSource = resultTable;
                for (int i = 1; i < resultTable.Columns.Count; i++)
                {
                    var ser = new Series(tempCol[columnsName[button.Text]], ViewType.Spline)
                        {
                            ArgumentDataMember = resultTable.Columns[0].ColumnName
                        };
                    
                    ser.ValueDataMembers.AddRange(resultTable.Columns[1].ColumnName);
                    chartControl1.Series.Add(ser);
                }
            }
                
        }

        private DataTable NewTable(DataTable table, int index1, int index2, string name1, string name2)
        {
            var result = new DataTable();

            result.Columns.Add(name1,typeof(double));
            result.Columns.Add(name2, typeof (double));
            for (int i = 0; i < table.Rows.Count; i++)
            {
                var row = result.NewRow();
                row[0] = table.Rows[i][index1];
                row[1] = table.Rows[i][index2];
                result.Rows.Add(row);
            }
            return result;
        }

        private void TimeTrackBar_ValueChanged(object sender, EventArgs e)
        {
            digitalGauge3.Text = string.Format("{0,3} c.", TimeTrackBar.Value);
        }

        private void timer2_Tick(object sender, EventArgs e)
        {
            string tankLevel1 = string.Format("{0,3} cm", tank1.Level/4);
            string tankLevel2 = string.Format("{0,3} cm", tank2.Level/4);
            digitalGauge1.Text = tankLevel1;
            digitalGauge2.Text = tankLevel2;
        }

        private void Form1Load(object sender, EventArgs e)
        {
            trackBar1.Maximum = tank1.Size.Height;
            trackBar2.Maximum = tank2.Size.Height;
            tank1.Level = 1;
            splitContainerControl1.SplitterPosition = Width / 3;
        }

        private void CockTrackBar1_ValueChanged(object sender, EventArgs e)
        {
            digitalGauge4.Text = string.Format("KPAH1 {0,2}", (float) CockTrackBar1.Value/10.0f);
        }

        private void CockTrackBar2_ValueChanged(object sender, EventArgs e)
        {
            digitalGauge5.Text = string.Format("KPAH2 {0,2}", (float)CockTrackBar2.Value / 10.0f);
        }

        private void tauTrackBar_ValueChanged(object sender, EventArgs e)
        {
            digitalGauge6.Text = string.Format("Tu {0,3}", tauTrackBar.Value);
        }

        private void kpTrackBar_ValueChanged(object sender, EventArgs e)
        {
            digitalGauge7.Text = string.Format("Kp {0,2}", kpTrackBar.Value / 10.0f);
        }

    }
}




